<script setup lang="ts">
import { h, ref, reactive, onMounted } from 'vue'
import { NModal, NCard, NForm, NSpace, NFormItem, NInput, NButton, NDataTable, NPagination, NPopconfirm, useNotification, useDialog, NUpload, NUploadDragger, NIcon, NText } from 'naive-ui'
import type { UploadCustomRequestOptions } from 'naive-ui'
import { CloudUploadOutlined } from '@vicons/antd'
import http from '@/tools/http'
import { useUserStore } from '@/stores/userStore'

const userStore = useUserStore()
const dialog = useDialog()

type RowData = {
    fileId: string
    fileStorageType: string
    fileName?: string
    fileType?: string
    fileLocation?: string
    md5: string
    uploadTime: string
    uploadUser?: string
}

const fileInfoTableColumns: any = [
    {
        type: 'selection',
        width: 40
    }, {
        title: "文件md5",
        key: "md5",
        width: 280
    }, {
        title: "文件名称",
        key: "fileName",
        width: 150,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "文件类型",
        key: "fileType",
        width: 80,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "文件存储地址",
        key: "fileLocation",
        width: 240,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "上传时间",
        key: "uploadTime",
        width: 159
    }, {
        title: "上传人",
        key: "uploadUser",
        width: 100
    }, {
        title: "操作",
        key: "actions",
        width: 132,
        fixed: 'right',
        render(rowData: RowData, rowIndex: number) {
            return h(
                NSpace, null,
                () => [
                    h(
                        NButton,
                        {
                            size: "small",
                            onclick: () => downloadFile(rowData)
                        },
                        { default: () => "下载" }
                    ),
                    userStore.hasAuth("file-manage:delete") ? h(
                        NPopconfirm,
                        {
                            onPositiveClick: (e: MouseEvent) => deleteFileInfo()
                        },
                        {
                            trigger: () => {
                                return h(
                                    NButton,
                                    {
                                        size: "small",
                                        onclick: () => openDeleteFileInfo(rowData)
                                    },
                                    { default: () => "删除" }
                                )
                            },
                            default: () => { return "确认删除？" }
                        }
                    ) : null
                ]
            )
        }
    }
]

const fileInfoData = reactive<any>({
    list: [],
    pageNum: 1,
    pageSize: 10,
    pages: 1,
    total: 0
})

const fileInfoSearchFormValue = reactive({
    pageNum: 1,
    pageSize: 10,
    fileName: "",
    uploadUser: ""
})

onMounted(() => {
    pageFileInfo()
})

const visiable = ref<boolean>(false)
const formData = reactive({
    fileId: ""
})
const selectedRowKeys = ref<Array<string | number>>([])

function pageNumChange(pageNum: number) {
    fileInfoSearchFormValue.pageNum = pageNum
    pageFileInfo()
}

function pageSizeChange(pageSize: number) {
    fileInfoSearchFormValue.pageSize = pageSize
    pageFileInfo()
}

function openUploadFile() {
    visiable.value = true
}

function openDeleteFileInfo(row: any) {
    formData.fileId = row.fileId
}

function handleCheck(keys: Array<string | number>, rows: object[], meta: { row: object | undefined, action: 'check' | 'uncheck' | 'checkAll' | 'uncheckAll' }) {
    selectedRowKeys.value = keys
}

function pageFileInfo() {
    http.post("/file/page", fileInfoSearchFormValue).then(({ data }) => {
        fileInfoData.pageNum = data.data.pageNum
        fileInfoData.pageSize = data.data.pageSize
        fileInfoData.pages = data.data.pages
        fileInfoData.total = data.data.total
        fileInfoData.list.length = 0
        for (let i = 0; i < data.data.list.length; i++) {
            fileInfoData.list.push(data.data.list[i])
        }
    })
}

const notification = useNotification()

function deleteFileInfo() {
    http.post("/file/delete", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '删除成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageFileInfo()
        }
    })
}

function batchDeleteFile() {
    dialog.warning({
        title: '批量删除文件',
        content: '确定删除已选择的文件吗？',
        positiveText: '确定',
        negativeText: '取消',
        onPositiveClick: () => {
            const request = selectedRowKeys.value
            http.post("/file/batch/delete", request).then(({ data }) => {
                if (data.code === "0") {
                    notification['success']({
                        content: '删除成功',
                        meta: `${data.msg}`,
                        duration: 2500,
                        keepAliveOnHover: true
                    })
                    pageFileInfo()
                }
            })
        }
    })
}

function uploadFile({ file, data, headers, withCredentials, action, onFinish, onError, onProgress }: UploadCustomRequestOptions) {
    const request = new FormData()
    request.append('file', file.file as File, file.file?.name)
    http.post("/file/upload", request, {
        headers: {
            'Content-Type': 'multipart/form-data;charset=UTF-8'
        },
        onUploadProgress: function (uploadEvent) {
            if (uploadEvent.total) {
                const progress = uploadEvent.loaded / uploadEvent.total * 100
                onProgress({ percent: Math.ceil(progress) })
            }
        }
    }).then(({ data }) => {
        notification['success']({
            content: '上传成功',
            meta: `${data.msg}`,
            duration: 2500,
            keepAliveOnHover: true
        })
        visiable.value = false
        pageFileInfo()
        onFinish()
    })
}

function downloadFile(rowData: RowData) {
    formData.fileId = rowData.fileId
    http.post("/file/download", formData, {
        responseType: 'blob'
    }).then(({ headers, data }) => {
        let filename = "file"
        if (headers['content-disposition']) {
            filename = headers['content-disposition'].replace(/attachment; filename=(.*)/, '$1')
        }
        const blob = new Blob([data], { type: headers['content-type'] })
        let dom = document.createElement('a')
        let url = window.URL.createObjectURL(blob)
        dom.href = url
        dom.download = decodeURI(filename)
        dom.style.display = 'none'
        document.body.appendChild(dom)
        dom.click()
        if (dom.parentNode) {
            dom.parentNode.removeChild(dom)
        }
        window.URL.revokeObjectURL(url)
        notification['success']({
            content: '下载成功',
            meta: `文件下载成功`,
            duration: 2500,
            keepAliveOnHover: true
        })
    })

}
</script>

<template>
    <div id="flame-container">
        <div class="search">
            <n-form :model="fileInfoSearchFormValue" inline label-placement="left">
                <n-form-item label="文件名称" path="fileName">
                    <n-input v-model:value="fileInfoSearchFormValue.fileName" placeholder="请输入文件名称" clearable />
                </n-form-item>
                <n-form-item label="上传人" path="uploadUser">
                    <n-input v-model:value="fileInfoSearchFormValue.uploadUser" placeholder="请输入上传人" clearable />
                </n-form-item>
                <n-form-item>
                    <n-button attr-type="button" @click="pageFileInfo()">查询</n-button>
                </n-form-item>
            </n-form>
        </div>
        <div class="btn-group">
            <n-space>
                <n-button @click="openUploadFile()">上传文件</n-button>
                <n-button v-if="userStore.hasAuth('file-manage:batch-delete')" :disabled="selectedRowKeys.length === 0"
                    @click="batchDeleteFile()">批量删除</n-button>
            </n-space>
        </div>
        <div class="data-table">
            <n-data-table :scroll-x="1181" :scrollbar-props="{ trigger: 'none' }" style="height:100%" flex-height
                :row-key="(row: RowData) => row.fileId" :on-update-checked-row-keys="handleCheck"
                :columns="fileInfoTableColumns" :data="fileInfoData.list" :bordered="false" />
        </div>
        <div class="pagination">
            <n-pagination style="float:right" v-model:page="fileInfoData.pageNum" :page-size="fileInfoData.pageSize"
                :item-count="fileInfoData.total" :page-sizes="[5, 10, 30, 50, 100]" :on-update-page="pageNumChange"
                :on-update-page-size="pageSizeChange" show-quick-jumper show-size-picker />
        </div>
    </div>
    <n-modal v-model:show="visiable">
        <n-card style="width: 400px" title="上传文件">
            <n-upload :custom-request="uploadFile">
                <n-upload-dragger>
                    <div style="margin-bottom: 12px">
                        <n-icon size="48" :depth="3">
                            <CloudUploadOutlined />
                        </n-icon>
                    </div>
                    <n-text style="font-size: 16px">
                        点击或者拖动文件到该区域来上传
                    </n-text>
                </n-upload-dragger>
            </n-upload>
        </n-card>
    </n-modal>
</template>

<style scoped>
.display-flex-end {
    display: flex;
    width: 100%;
    justify-content: flex-end;
}
</style>